<?php

/**
 * This is the model class for table "{{gallery}}".
 *
 * The followings are the available columns in table '{{gallery}}':
 * @property integer $id
 * @property integer $accountId_
 * @property string $module
 * @property integer $module_id
 * @property integer $usage_id
 * @property integer $is_default
 * @property string $source
 * @property string $source_info
 * @property string $url_referrer
 * @property string $name
 * @property string $caption
 * @property string $alt
 * @property string $description
 * @property string $type
 * @property integer $width
 * @property integer $height
 * @property double $size
 * @property string $meta_data
 * @property integer $total_view
 * @property integer $status_code
 * @property string $create_timezone
 * @property string $create_timestamp
 * @property string $create_datetime
 * @property string $create_date
 * @property string $create_time
 * @property integer $create_by
 * @property string $update_timezone
 * @property string $update_timestamp
 * @property string $update_datetime
 * @property string $update_date
 * @property string $update_time
 * @property integer $update_by
 */
class Gallery extends AccountRecord {

    public $moduleId_;
    public $module_;
    public $file_;
    public $url_;
    public $embed_;
    
    public $usage_;
    public $default_;
    public $caption_;
    public $alt_;
    public $description_;
    public $captions_; // for multiple captions
    public $tags_;
    public $width_;
    public $height_;
    public $size_;

    public $_storageMode;
    
    public function init(){
        parent::init();
        $this->_storageMode=isset(Yii::app()->params['imageStorage'])? strtolower(Yii::app()->params['imageStorage']):'localhost';
    }
    
    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Photo the static model class
     */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return '{{gallery}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('module_, moduleId_, default_, caption_, tags_','filter','filter'=>'trim'),
            //array('caption_','filter','filter'=>array($obj=new CHtmlPurifier(),'purify')),
            
            array('module_', 'required', 'on'=>'create'),
            array('module_', 'length', 'max'=>45),
            array('moduleId_, usage_, width_, height_, size_', 'numerical', 'allowEmpty'=>false, 'integerOnly'=>true, 'on'=>'create'),
            
            array('default_', 'boolean'),
            array('caption_', 'length', 'max'=>'100'),
            array('tags_', 'length', 'max'=>'300'),
            array('url_','url','defaultScheme'=>'http'),
            array('moduleId_, module_, file_, url_, embed_, usage_, default_, caption_, tags_, width_, height_, size_', 'safe', 'on' => 'insert, userCreate, userUpdate, adminCreate, adminUpdate'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            // must include
            'creator' => array(self::BELONGS_TO, 'User', 'create_by'),
            'editor' => array(self::BELONGS_TO, 'User', 'update_by'),
            
            //custom
            'account'=> array(self::BELONGS_TO, 'Account', 'account_id', 'scopes'=>array('accessible')),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'caption_'=>'Caption',
        );
    }

    /**
     * scopes
     */   
    public function scopes() {
        $t = $this->getTableAlias(false);
        return array(
            'primary'=>array(
                'condition' => implode(' AND ',array(
                    $t.'.is_default=1',
                )),
            ),
            'published'=>array(
                'condition' => $t.'.status_code <> :activeStatus'.$t,
                'params' => array(
                    ':activeStatus'.$t => Option::STATUS_ACTIVE,
                ),
            ),
            'ordered'=>array(
                'order'=>implode(',',array(
                    $t.'.is_default DESC',
                    $t.'.create_time DESC',
                )),
            ),
            'accessible'=>array(
                'condition' => $t.'.status_code <> :deletedStatus'.$t,
                'params' => array(
                    ':deletedStatus'.$t => Option::STATUS_DELETED,
                ),
            ),
        );
    }

    public function module($module = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t.'.module = :module'.$t,
            'params' => array(
                ':module'.$t => strtolower($module),
            ),
        ));
        return $this;
    }

    public function moduleId($id = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t . '.module_id = :moduleId'.$t,
            'params' => array(
                ':moduleId'.$t => (int)$id,
            ),
        ));
        return $this;
    }

    public function account($account = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t.'.account_id = :account'.$t,
            'params' => array(
                ':account'.$t => (int)$account,
            ),
        ));
        return $this;
    }
    
    public function usage($usage = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t.'.usage_id = :usage'.$t,
            'params' => array(
                ':usage'.$t => (int)$usage,
            ),
        ));
        return $this;
    }
    
    public function source($source = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t.'.source = :source'.$t,
            'params' => array(
                ':source'.$t => strtolower($source),
            ),
        ));
        return $this;
    }
    
    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;


        return new ActiveDataProvider($this->accessible(), array(
            'criteria' => $criteria,
        ));
    }

    protected function beforeSave() {
        if (parent::beforeSave()) {
            $this->module_id = $this->moduleId_;
            $this->module = strtolower($this->module_);

            $this->account_id=$this->accountId_;
            
            if ($this->isNewRecord) {
                $this->usage_id=$this->usage_;
                $this->setCreateDateTime();
            } else {
                $this->setUpdateDateTime();
            }
            return true;
        }else{
            return false;
        }
    }

    protected function afterSave() {
        parent::afterSave();
        //$this->saveLog();
    }

    public function updateCaptions(){
        foreach($this->captions_ as $id=>$caption ){
            $this->caption_=$caption;
            if($this->validate(array('caption_'))){
                if($this->updateByPk($id, array('caption'=>$this->caption_))){
                    $this->addError('error', Lang::t('gallery.editor.error.update.caption.fail', array('imageId'=>$id)));
                }
            }else{
                $this->addError('error', Lang::t('gallery.editor.error.update.caption.fail', array('imageId'=>$id)));
            }
        }
        return true;
    }
    
    public function deleteRecord() {        
        switch(Yii::app()->params['imageStorage']){
            case 'flickr':
                if($this->deleteFromFlickr()){
                    return $this->delete();
                }
                break;
            
            case 'localhost':
            default:
                if ($this->removeFile()) {
                    return $this->delete();
                }
                break;
        }
        return false;
    }

    public function removeFile() {
        $filePath=implode('/', array_filter(array(
            $this->uploadPath,
            $this->name,
        )));
        if(file_exists($filePath) && unlink($filePath)){
            $fileTB = implode('/', array_filter(array(
                $this->uploadPath,
                'tb/tb_'.$this->name,
            )));
            if(file_exists($fileTB)){
                return unlink($fileTB);
            }    
        }
        return true;
    }

    public function isPathExist($directory) {
        if (!file_exists($directory)) {
            if (@mkdir($directory, 0777, true)) {
                if (!is_writable($directory)) {
                    if (chmod($directory)) {
                        return true;
                    }
                }
            }
        }
    }

    public function addCover() {        

        /*
          //example that transfers a file from the local host to a remote server using the HTTP protocol's PUT method:
          $file = "testfile.txt";

          $c = curl_init();
          curl_setopt($c, CURLOPT_URL, "http://example.com/putscript");
          curl_setopt($c, CURLOPT_USERPWD, "username:password");
          curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($c, CURLOPT_PUT, true);
          curl_setopt($c, CURLOPT_INFILESIZE, filesize($file));

          $fp = fopen($file, "r");
          curl_setopt($c, CURLOPT_INFILE, $fp);

          curl_exec($c);

          curl_close($c);
          fclose($fp);
         */

        //$rnd = rand(0,9999);  // generate random number between 0-9999

        $this->scenario='insert';
        $directory = $this->uploadPath;
        $this->isPathExist($directory);
        
        $fileName=$this->generateFileName('cover_'. $this->file_->name);
        $img = Yii::app()->simpleImage->load($this->file_->tempName);
        $img->resizeCrop(0, $this->cropFromTop_, Yii::app()->params['coverImageWidth'], Yii::app()->params['coverImageHeight'], true, false);
        
        if($img->save($directory . '/' . $fileName)){
            $this->generateThumbnail($directory, $fileName);
            $this->name = $fileName;
            $this->type = $this->file_->type;
            $this->size = $this->file_->size;
            $this->caption = $this->caption_;
            $this->is_default = false;
            $this->is_cover = true;
            $this->status_code = Option::STATUS_ACTIVE;
            if($this->save()){
                $this->updateAll(array('status_code'=>Option::STATUS_DELETED), implode(' AND ', array(
                    'module = :module',
                    'module_id = :moduleId',
                    'is_cover = true',
                    'id <> :id',
                )), array(
                    ':module'=>$this->module_,
                    ':moduleId'=>$this->moduleId_,
                    ':id'=>$this->id,
                ));
                return true;
            }else
                return false;
        }
        else
            return false;
    }
    
    public function removeCover($module, $moduleId){
        $model = $this->findByAttributes(array(
                'module'=>$module,
                'module_id'=>$moduleId,
                'is_cover'=>true,
            ), implode(' AND ', array(
                'status_code <> :deletedStatus',
            )), array(
                ':deletedStatus' => Option::STATUS_DELETED,
            )
        );
        
        if(empty($model)) return false;
        return $model->saveAttributes(array(
            'status_code'=>Option::STATUS_DELETED,
        ));
    }
    
    public function addAvatar(){

        /*
          //example that transfers a file from the local host to a remote server using the HTTP protocol's PUT method:
          $file = "testfile.txt";

          $c = curl_init();
          curl_setopt($c, CURLOPT_URL, "http://example.com/putscript");
          curl_setopt($c, CURLOPT_USERPWD, "username:password");
          curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($c, CURLOPT_PUT, true);
          curl_setopt($c, CURLOPT_INFILESIZE, filesize($file));

          $fp = fopen($file, "r");
          curl_setopt($c, CURLOPT_INFILE, $fp);

          curl_exec($c);

          curl_close($c);
          fclose($fp);
         */

        //$rnd = rand(0,9999);  // generate random number between 0-9999
        $this->scenario='insert';
        $directory = $this->uploadPath;
        $this->isPathExist($directory);

        $fileName=$this->generateFileName('avatar_'. $this->file_->name);
        $img = Yii::app()->simpleImage->load($this->file_->tempName);
        $img->resizeCrop(0, $this->cropFromTop_, Yii::app()->params['avatarImageWidth'], Yii::app()->params['avatarImageHeight'], false, true);
        
        if($img->save($directory . '/' . $fileName)){
            $this->generateThumbnail($directory, $fileName);
            $this->name = $fileName;
            $this->type = $this->file_->type;
            $this->size = $this->file_->size;
            $this->caption = $this->caption_;
            $this->is_default = false;
            $this->is_avatar = true;
            $this->status_code = Option::STATUS_ACTIVE;
            if($this->save()){
                $this->updateAll(array('status_code'=>Option::STATUS_DELETED), implode(' AND ', array(
                    'module = :module',
                    'module_id = :moduleId',
                    'is_avatar = true',
                    'id <> :id',
                )), array(
                    ':module'=>$this->module_,
                    ':moduleId'=>$this->moduleId_,
                    ':id'=>$this->id,
                ));
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }    
    
    public function addRecord(){        
        
        if($this->_storageMode=='localhost'){
            $directory=$this->uploadPath;
            $this->isPathExist($directory.'/'.strtolower(Yii::app()->params['imageOriginalDimensions']));
        }else{
            $directory='';
        }
        
        foreach($this->file_ as $file){
            if(!$this->uploadFile($directory,$file)) continue;
        }//end foreach
        $this->setDefault($this->module_, $this->moduleId_);
    }
    
    public function addUrlRecord(){
        if(!is_array($this->url_))
            $this->url_[]=$this->url_;
        
        foreach($this->url_ as $key=>$image){
            list($url, $queryString) = explode('?', $image);            
            $params = array();
            if (!empty($queryString)){
                foreach (explode('&', $queryString) as $query) {
                    list($param, $value) = explode('=', $query);
                    $params[$param] = $value;
                }
            }
            $model=new $this;
            $model->moduleId_=$this->moduleId_;
            $model->module_=$this->module_;
                        
            $model->url_referrer = $url;
            list($model->width, $model->height, $model->type) = getimagesize($url);
            $model->type = image_type_to_mime_type($model->type);
            if(isset($params['size'])){ $model->size = $params['size'];}
            if(isset($params['caption'])){ $model->caption = $params['caption'];}
            $model->status_code = Option::STATUS_ACTIVE;
            if ($model->save(true)) {
                //exit;
            } else {
                $this->addErrors($model->getErrors());
            }
        }
        $this->setDefault($this->module_, $this->moduleId_);
    }
    
    public function addEmbedRecord(){
        foreach($this->imageEmbed_ as $image){
            $model=new $this;
            
            $model->moduleId_=$this->moduleId_;
            $model->module_=$this->module_;
            
            $model->url_referrer = $image->url;
            $model->width= $image->width;
            $model->height=$image->height;
            $model->size = $image->size;
            $model->caption = $image->caption;
            $model->status_code = Option::STATUS_ACTIVE;
            if ($model->save(true)) {
                //exit;
            } else {
                $this->addErrors($model->getErrors());
            }
        }
    }
    
    /*
     * Flickr
     */
    public function uploadToFlickr(&$file){
        $photoId=Yii::app()->flickr->upload($file->tempName, $file->name);
        if($photoId){
            $photoInfo=Yii::app()->flickr->getPhotoInfo();
            $model=new $this;
            $model->source='flickr';
            $model->source_info=CJSON::encode(array(
                'photoinfo'=>$photoInfo,
                'photoSizes'=>Yii::app()->flickr->getPhotoSizes(),
            ));
            $model->url_referrer=Yii::app()->flickr->getPhotoUrl();
            $model->name=$file->name;
            $model->type = $file->type;
            $model->size = $file->size;
            $model->moduleId_ = $this->moduleId_;
            $model->module_ = $this->module_;
            $model->status_code = Option::STATUS_ACTIVE;
            if ($model->save(true)) {
                return true;
            } else {
                $this->addErrors($model->getErrors());
                return false;
            }
        }else{
            return false;
        }
    }
    
    public function deleteFromFlickr(){
        $info=CJSON::decode($this->source_info);
        return Yii::app()->flickr->deletePhoto($info['photoinfo']['photo']['id']);
    }
    
    public function uploadToRemote(&$file){
        /*
        //example that transfers a file from the local host to a remote server using the HTTP protocol's PUT method:
        $file = "testfile.txt";

        $c = curl_init();
        curl_setopt($c, CURLOPT_URL, "http://example.com/putscript");
        curl_setopt($c, CURLOPT_USERPWD, "username:password");
        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($c, CURLOPT_PUT, true);
        curl_setopt($c, CURLOPT_INFILESIZE, filesize($file));

        $fp = fopen($file, "r");
        curl_setopt($c, CURLOPT_INFILE, $fp);

        curl_exec($c);

        curl_close($c);
        fclose($fp);
       */
        //$rnd = rand(0,9999);  // generate random number between 0-9999        
        return false;
    }
    
    public function uploadFile($directory, &$file){        
        switch($this->_storageMode){
            case 'remote':
                return $this->uploadToRemote($file);
                break;
            case 'flickr':
                return $this->uploadToFlickr($file);
                break;
            case 'localhost':
            default:
                $fileName=$this->generateFileName($file->name);
                //if ($file->saveAs($directory . '/' . $fileName)) {
                
                $dimensions=strtolower(Yii::app()->params['imageOriginalDimensions']);
                list($width,$height)=explode('x',$dimensions);
                $img=Yii::app()->simpleImage->load($file->tempName);
                if($img->getWidth()> $width){ $img->resizeToWidth($width); }
                if($img->save($directory . '/' .$dimensions . '/' . $fileName)){
                    $this->generateThumbnail($directory, $fileName);
                    $model=new $this;
                    $model->name=$fileName;
                    $model->type=$file->type;
                    $model->size=$file->size;
                    list($model->width, $model->height)=getimagesize($directory . '/' . $dimensions . '/' . $fileName);
                    $model->moduleId_=$this->moduleId_;
                    $model->module_=$this->module_;
                    $model->default_=$this->default_;
                    $model->status_code = Option::STATUS_ACTIVE;
                    if($model->save(true)){
                        return true;
                    }else{
                        $this->addErrors($model->getErrors());
                        return false;
                    }
                }else{
                    return false;
                }
                break;
        }
        return false;
    }
    
    public function generateThumbnail($directory, $file){
        
        $options=array(
            'imageSquareDimensions',
            'imageLargeSquareDimensions',
            'imageThumbnailDimensions',
            'imageSmallDimensions',
            'imageMediumDimensions',
        );
        
        foreach($options as $value){
            if(isset(Yii::app()->params[$value]) && !empty(Yii::app()->params[$value])){
                $dimensions[]=Yii::app()->params[$value];
            }
        }
        
        foreach($dimensions as $dimension){
            $thumbnailPath=$directory.'/'.$dimension;
            $this->isPathExist($thumbnailPath);
            list($width, $height)=explode('x',strtolower($dimension));
            $img = Yii::app()->simpleImage->load($directory.'/'.strtolower(Yii::app()->params['imageOriginalDimensions']).'/'.$file);
            
            if($width===$height){
                $img->fitToBox($width);
            }else{
                $img->resizeToWidth($width);
            }
            $img->save($thumbnailPath.'/'.$file);
        }        
    }
    
    public function setDefault(&$module, &$moduleId, $id=null){
        $model=$this->primary()->accessible()->module($module)->moduleId($moduleId)->find();
        if($model && $id){
            $newDefault=$this->accessible()->module($module)->moduleId($moduleId)->findByPk((int)$id);
            if($newDefault->saveAttributes(array('is_default'=>1))){
                $model->saveAttributes(array('is_default'=>0));
            }
        }elseif(empty($model) && empty($id)){
            $model=$this->accessible()->module($module)->moduleId($moduleId)->find();
            if(!empty($model))
                $model->saveAttributes(array('is_default'=>1));
        }
    }
    
    public function generateFileName($fileName){
        /*
        return implode('-', array_filter(array(
            strtolower($this->module_),
            $this->moduleId_,
            time(),
            $fileName,
        )));*/

        $tempName = strtolower($fileName);
        $fileName = strtr($tempName, array(
            '.jpg'=>'',
            '.jpeg'=>'',
            '.png'=>'',
            '.gif'=>'',
        ));
        $extension = str_replace($fileName, '', $tempName);
        
        return implode('-', array_filter(array(
            $this->urlFormat($fileName),
            strtolower($this->module_),
            $this->moduleId_,
            time().$extension,
        )));
    }   
    
    public function getUploadPath() {
        $uploadPath=Yii::app()->params['imagePath'];
        $format = 'Y/M/d';
        switch ($this->scenario) {
            case 'insert':
            case 'userCreate':
            case 'userUpdate':
            case 'adminCreate':
            case 'adminUpdate':
                return implode('/', array_filter(array(
                    str_replace(Yii::app()->params['mediaDomain'], Yii::app()->params['relativeMediaPath'], $uploadPath),
                    strtolower(date($format, time())),
                )));
                break;
            case 'delete':
            case 'userDelete':
            case 'adminDelete':
                return implode('/', array_filter(array(
                    str_replace(Yii::app()->params['mediaDomain'], Yii::app()->params['relativeMediaPath'], $uploadPath),
                    strtolower(date($format, strtotime($this->create_time))),
                )));
                break;
            
            case 'update':
            default:
                return implode('/', array_filter(array(
                    $uploadPath,
                    strtolower(date($format, strtotime($this->create_time))),
                )));
                break;
        }//end switch
    }

    public function getFileName() {
        return CHtml::encode($this->name);
    }

    public function getFilePath(){
        return implode('/', array_filter(array(
            $this->uploadPath, 
            rawurlencode($this->fileName),
            )));
    }
    
    public function getFileCaption() {
        return CHtml::encode($this->caption);
    }

    public function getFileType() {
        return CHtml::encode($this->type);
    }

    public function getFileWidth(){
        return (int)$this->width;
    }
    
    public function getFileHeight(){
        return (int)$this->height;
    }    
    
    public function getFileSize() {
        return CHtml::encode((double)$this->size);
    }

    public function getTotalView(){
        return (int)$this->total_view;
    }
    
    public function getIsDefault(){
        return !empty($this->is_default);
    }
    
    public function getTags() {
        return CHtml::encode($this->tags);
    }

    public function getIsUrlReferrer(){
        return !empty($this->url_referrer);
    }
    
    public function getUrlReferrer(){
        return $this->url_referrer;
    }
    
    public function getIsOutsource(){
        
    }
    
    public function getSquareThumbnail(){
        return $this->isUrlReferrer? $this->urlReferrer:
                implode('/', array_filter(array(
                    $this->uploadPath,
                    Yii::app()->params['imageSquareDimensions'],
                    rawurlencode($this->fileName),
                )));
    }
    
    public function getLargeSquareThumbnail(){
        return $this->isUrlReferrer? $this->urlReferrer:
                implode('/', array_filter(array(
                    $this->uploadPath,
                    Yii::app()->params['imageLargeSquareDimensions'],
                    rawurlencode($this->fileName),
                )));
    }
    
    public function getThumbnail($value=null) {
        return $this->isUrlReferrer? $this->urlReferrer:
                implode('/', array_filter(array(
                    $this->uploadPath,
                    Yii::app()->params['imageThumbnailDimensions'],
                    rawurlencode($this->fileName),
                )));
    }    
    
    public function getSmallThumbnail(){
        return $this->isUrlReferrer? $this->urlReferrer:
                implode('/', array_filter(array(
                    $this->uploadPath,
                    Yii::app()->params['imageSmallDimensions'],
                    rawurlencode($this->fileName),
                )));
    }    
    
    public function getMediumThumbnail(){
        return $this->isUrlReferrer? $this->urlReferrer:
                implode('/', array_filter(array(
                    $this->uploadPath,
                    Yii::app()->params['imageMediumDimensions'],
                    rawurlencode($this->fileName),
                )));
    }
    
    public function getOriginalFile(){
        return $this->isUrlReferrer? $this->urlReferrer:
                implode('/', array_filter(array(
                    $this->uploadPath,
                    Yii::app()->params['imageOriginalDimensions'],
                    rawurlencode($this->fileName),
                )));
    }

    public function getImage() {
        return $this->isUrlReferrer? $this->urlReferrer: 
                implode('/', array_filter(array(
                    $this->uploadPath,
                    rawurlencode($this->fileName),
                )));
    }

}//end class